
 <!DOCTYPE HTML>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  
    <title>RyanHuen</title>
    <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
    
    <meta name="author" content="RyanHuen">
    

    
    <meta name="description" content="某Android开发程序员，兼做Framework，同时在学习chrome内核、机器学习。多多指教！">
<meta property="og:type" content="website">
<meta property="og:title" content="RyanHuen">
<meta property="og:url" content="http://www.ryanhuen.tech/index.html">
<meta property="og:site_name" content="RyanHuen">
<meta property="og:description" content="某Android开发程序员，兼做Framework，同时在学习chrome内核、机器学习。多多指教！">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="RyanHuen">
<meta name="twitter:description" content="某Android开发程序员，兼做Framework，同时在学习chrome内核、机器学习。多多指教！">

    
    <link rel="alternative" href="/atom.xml" title="RyanHuen" type="application/atom+xml">
    
    
    <link rel="icon" href="/img/favicon.ico">
    
    
    <link rel="apple-touch-icon" href="/img/jacman.jpg">
    <link rel="apple-touch-icon-precomposed" href="/img/jacman.jpg">
    
    <link rel="stylesheet" href="/css/style.css">
</head>

  <body>
    <header>
      
<div>
		
			<div id="imglogo">
				<a href="/"><img src="/img/logo.png" alt="RyanHuen" title="RyanHuen"/></a>
			</div>
			
			<div id="textlogo">
				<h1 class="site-name"><a href="/" title="RyanHuen">RyanHuen</a></h1>
				<h2 class="blog-motto">I hope I can protect the one thing I can&#39;t live without.</h2>
			</div>
			<div class="navbar"><a class="navbutton navmobile" href="#" title="菜单">
			</a></div>
			<nav class="animated">
				<ul>
					<ul>
					 
						<li><a href="/">首页</a></li>
					
						<li><a href="/archives">历程</a></li>
					
						<li><a href="/categories">分类</a></li>
					
						<li><a href="/tags">标签</a></li>
					
						<li><a href="/about">关于</a></li>
					
					<li>
 					
					<form class="search" action="//google.com/search" method="get" accept-charset="utf-8">
						<label>Search</label>
						<input type="search" id="search" name="q" autocomplete="off" maxlength="20" placeholder="搜索" />
						<input type="hidden" name="q" value="site:www.ryanhuen.tech">
					</form>
					
					</li>
				</ul>
			</nav>			
</div>
    </header>
    <div id="container">
      <div id="main">

   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/21/rx-backpressure/" title="RxJava基础篇(四):BackPressure简介" itemprop="url">RxJava基础篇(四):BackPressure简介</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-21T02:46:45.000Z" itemprop="datePublished"> 发表于 2017-02-21</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="orgbebdb22"></a></p>
<h1 id="前提场景："><a href="#前提场景：" class="headerlink" title="前提场景："></a>前提场景：</h1><ol>
<li><p>当zip操作进行时，第一个上游发射事件速度飞快，累计到1000个事件后，第二个上游才发射第一个事件。此时，就会造成第一个上游积压了999个事件，等待第二个上游发射新事件进行zip操作。</p>
</li>
<li><p>由此可见，当两个上游事件发射事件的速度不一致时，会导致很多问题：</p>
<ol>
<li>时序、同步、效率等等。</li>
</ol>
</li>
<li><p>尤其是像上述实例，第一个上游飞速发射事件，就会因为第二个上游发射事件的缓慢而造成事件的积压，如果不希望积压下来的事件丢失，就需要一个机制对事件进行缓存起来。</p>
</li>
<li><p>而这个缓存机制，是每一个上游进行发射事件的时候，都会分配一个容器，对这个上游发射的事件进行缓存起来。看上去，这个容器必须知道事件的先后顺序，必须是先进后出的形式。因此，采用队列的数据结构是最合适的行为。</p>
</li>
<li><p>那么问题来了：</p>
<ol>
<li><p>缓存事件的队列是否有上限？</p>
<ol>
<li>没有。因此只要事件在不断地发射，队列就会不断缓存。直到出现OOM异常的时候，程序报错终止。</li>
</ol>
</li>
<li><p>因此，为了解决这个问题，我们引入了BackPressure这个概念。</p>
</li>
</ol>
</li>
</ol>
<p><a id="orgc091a20"></a></p>
<h1 id="BackPressure："><a href="#BackPressure：" class="headerlink" title="BackPressure："></a>BackPressure：</h1><ol>
<li><p>既然事件发射的速度这么快，缓存都快要满了，那么我们有两种解决方案：</p>
<ol>
<li><p>减少进入队列的事件</p>
<ol>
<li>有可能造成事件丢失,因为要减少事件进入队列，而上游发送的速度不变的情况下，肯定会出现事件的丢失。</li>
</ol>
</li>
<li><p>减缓上游的发射频率</p>
<ol>
<li>减缓了发射频率就从源头上解决了事件的速度过快的问题。当然大家可能又会有问题：我们一开始的需求可能就是上游发射事件速度很快啊，如果速度不能减缓呢？</li>
</ol>
</li>
<li><p>以上两种方式，看上去都不是非常合适的解决方案。那么我们到底应该怎么做呢？</p>
<ol>
<li><p>下游决定上游！</p>
<ol>
<li><p>是否可以这样，由下游来决定我处理多少事件，然后通知上游给我发射多少事件。通过这样一种机制，我们能够使上下游在一定程度上维持在一个平缓的程度，每次的发射事件和接收事件都能达到一个平衡。</p>
</li>
<li><p>下游能处理多少事件，上游就发射多少，等下游处理完了再通知上游继续发射。这个方案，看上去是最合理的。</p>
</li>
<li><p>那么此时，就引入了一种新的上下游订阅方式——Flowable。</p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/RxJava基础/">RxJava基础</a><a href="/tags/BackPressure/">BackPressure</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/21/rx-backpressure/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/21/rx-backpressure/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/17/rx-base-operator/" title="RxJava基础篇(三):常用操作符" itemprop="url">RxJava基础篇(三):常用操作符</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-17T02:33:45.000Z" itemprop="datePublished"> 发表于 2017-02-17</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="orga8730bd"></a></p>
<h1 id="变换："><a href="#变换：" class="headerlink" title="变换："></a>变换：</h1><ol>
<li>RX提供了对事件序列进行变换的支持，这是核心功能之一。就是将事件序列中的对象进行加工处理，转换成不同的事件或者事件序列（简单点说：发送出来的事件，我们可以理解成一个对象，事件序列就是对象序列。对事件进行改造加工，就是对对象进行额外处理）。</li>
</ol>
<p><a id="orgd425b69"></a></p>
<h1 id="变换操作符："><a href="#变换操作符：" class="headerlink" title="变换操作符："></a>变换操作符：</h1><p><a id="org5e5b315"></a></p>
<h2 id="Map："><a href="#Map：" class="headerlink" title="Map："></a>Map：</h2><ol>
<li><p>对上游发送的每一个事件，应用一个操作，让每一个经过这个操作的事件，都能按照指定的方式去发生变换。</p>
</li>
<li><p>图例：</p>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/rx-operator-1.png?watermark/2/text/Unlhbkh1ZW4=/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0JCQkJCQg==/dissolve/100/gravity/SouthWest/dx/10/dy/10" alt="img"></p>
</li>
<li><p>通过Map我们可以将上游发射过来的任意事件转换为我们想要的任意类型：</p>
<ol>
<li>Object、集合、自定义对象等等等等</li>
</ol>
</li>
<li><p>请看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">            e.onNext(<span class="string">"事件1"</span>);</div><div class="line">            e.onNext(<span class="string">"事件2"</span>);</div><div class="line">            e.onNext(<span class="string">"事件3"</span>);</div><div class="line">            e.onNext(<span class="string">"事件4"</span>);</div><div class="line">            e.onComplete();</div><div class="line">        &#125;</div><div class="line">    &#125;).map(<span class="keyword">new</span> Function&lt;String, String&gt;() &#123;</div><div class="line">            <span class="meta">@Override</span></div><div class="line">            <span class="function"><span class="keyword">public</span> String <span class="title">apply</span><span class="params">(String string)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">                <span class="comment">// 通过变换操作，拼接字符串，随后返回</span></div><div class="line">                <span class="keyword">return</span> <span class="string">"this is resule:"</span> + string;</div><div class="line">            &#125;</div><div class="line">        &#125;).subscribe(<span class="keyword">new</span> Consumer&lt;String&gt;() &#123;</div><div class="line">                <span class="meta">@Override</span></div><div class="line">                <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(String s)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">                    Log.d(TAG, <span class="string">"accept: "</span> + s);</div><div class="line">                &#125;</div><div class="line">            &#125;);</div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="orgcb1608a"></a></p>
<h2 id="FlatMap："><a href="#FlatMap：" class="headerlink" title="FlatMap："></a>FlatMap：</h2><ol>
<li><p>将一个发送事件的上游Observable变换成多个发送事件的Observables，然后将他们发射的事件合并后，放入一个单独的Observable中，随后交给下游处理。（可以理解成，第一个上游，创建了多个上游发射事件，随后将这多个上游发射的事件汇总到一起，交给下游处理）</p>
</li>
<li><p>图例：</p>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/rx-operator-2.png?watermark/2/text/Unlhbkh1ZW4=/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0JCQkJCQg==/dissolve/100/gravity/SouthWest/dx/10/dy/10" alt="img"></p>
</li>
</ol>
<ol>
<li><p>注意：FlatMap并不保证事件的发送顺序</p>
</li>
<li><p>请看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line">Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">     <span class="meta">@Override</span></div><div class="line">     <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">         e.onNext(<span class="string">"事件1"</span>);</div><div class="line">         e.onNext(<span class="string">"事件2"</span>);</div><div class="line">         e.onNext(<span class="string">"事件3"</span>);</div><div class="line">         e.onNext(<span class="string">"事件4"</span>);</div><div class="line">         e.onComplete();</div><div class="line">     &#125;</div><div class="line"> &#125;).flatMap(<span class="keyword">new</span> Function&lt;String, ObservableSource&lt;String&gt;&gt;() &#123;</div><div class="line">     <span class="meta">@Override</span></div><div class="line">     <span class="function"><span class="keyword">public</span> ObservableSource&lt;String&gt; <span class="title">apply</span><span class="params">(String string)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">         <span class="keyword">final</span> List&lt;String&gt; list = <span class="keyword">new</span> ArrayList&lt;String&gt;();</div><div class="line">         <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">3</span>; i++) &#123;</div><div class="line">             list.add(<span class="string">"I am value:"</span> + string);</div><div class="line">         &#125;</div><div class="line">         <span class="keyword">return</span> Observable.fromIterable(list)<span class="comment">/*</span></div><div class="line">                                              * 后续代码加入了delay功能，</div><div class="line">                                              * 标示发送事件延迟10毫秒</div><div class="line">                                              */.delay(<span class="number">10</span>, TimeUnit.MILLISECONDS);</div><div class="line">     &#125;</div><div class="line"> &#125;).subscribe(<span class="keyword">new</span> Consumer&lt;String&gt;() &#123;</div><div class="line">     <span class="meta">@Override</span></div><div class="line">     <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(String s)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">         Log.d(TAG, <span class="string">"accept: "</span> + s);</div><div class="line">     &#125;</div><div class="line"> &#125;);</div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="org1ee809f"></a></p>
<h2 id="ConcatMap："><a href="#ConcatMap：" class="headerlink" title="ConcatMap："></a>ConcatMap：</h2><ol>
<li><p>与FlatMap的效果几乎一模一样</p>
</li>
<li><p>图例：</p>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/rx-operator-3.png?watermark/2/text/Unlhbkh1ZW4=/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0JCQkJCQg==/dissolve/100/gravity/SouthWest/dx/10/dy/10" alt="img"></p>
</li>
</ol>
<ol>
<li><p>区别：</p>
</li>
<li><p>它的结果是严格按照上游的发送顺序来进行发送的</p>
</li>
<li><p>请看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line">Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">            e.onNext(<span class="string">"事件1"</span>);</div><div class="line">            e.onNext(<span class="string">"事件2"</span>);</div><div class="line">            e.onNext(<span class="string">"事件3"</span>);</div><div class="line">            e.onNext(<span class="string">"事件4"</span>);</div><div class="line">            e.onComplete();</div><div class="line">        &#125;</div><div class="line">    &#125;).concatMap(<span class="keyword">new</span> Function&lt;String, ObservableSource&lt;String&gt;&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> ObservableSource&lt;String&gt; <span class="title">apply</span><span class="params">(String string)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">            <span class="keyword">final</span> List&lt;String&gt; list = <span class="keyword">new</span> ArrayList&lt;String&gt;();</div><div class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">3</span>; i++) &#123;</div><div class="line">                list.add(<span class="string">"I am value:"</span> + string);</div><div class="line">            &#125;</div><div class="line">            <span class="keyword">return</span> Observable.fromIterable(list)<span class="comment">/*</span></div><div class="line">                                                 * 后续代码加入了delay功能，</div><div class="line">                                                 * 标示发送事件延迟10毫秒</div><div class="line">                                                 */.delay(<span class="number">10</span>, TimeUnit.MILLISECONDS);</div><div class="line">        &#125;</div><div class="line">    &#125;).subscribe(<span class="keyword">new</span> Consumer&lt;String&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(String s)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">            Log.d(TAG, <span class="string">"accept: "</span> + s);</div><div class="line">        &#125;</div><div class="line">    &#125;);</div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="org7502f58"></a></p>
<h2 id="Zip："><a href="#Zip：" class="headerlink" title="Zip："></a>Zip：</h2><ol>
<li><p>通过一个函数将两个个Observable发送的事件整合到一起，将他们发送给下游。</p>
</li>
<li><p>组合的顺序是严格按照事件发送的顺序来进行的，也就是说每个上游的事件顺序都是对应进行zip处理的。</p>
</li>
<li><p>zip整合后的事件发射个数：取两个个上游中，事件个数最少的上游的个数为准。因为zip是从每个上游取出一个事件进行处理，一旦有任何一个上游的事件取完，zip就结束了。</p>
</li>
<li><p>具体流程：</p>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/rx-operator-4.png?watermark/2/text/Unlhbkh1ZW4=/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0JCQkJCQg==/dissolve/100/gravity/SouthWest/dx/10/dy/10" alt="img"></p>
</li>
</ol>
<ol>
<li><p>请看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div></pre></td><td class="code"><pre><div class="line">Observable&lt;String&gt; observable1 = Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">               e.onNext(<span class="string">"01我是："</span>);</div><div class="line">               e.onNext(<span class="string">"02我是："</span>);</div><div class="line">               e.onNext(<span class="string">"03我是："</span>);</div><div class="line">               e.onNext(<span class="string">"04我是："</span>);</div><div class="line">               e.onComplete();</div><div class="line">           &#125;</div><div class="line">       &#125;).subscribeOn(Schedulers.io());</div><div class="line">       Observable&lt;Integer&gt; observable2 = Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;Integer&gt;() &#123;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;Integer&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">               e.onNext(<span class="number">1</span>);</div><div class="line">               e.onNext(<span class="number">2</span>);</div><div class="line">               e.onNext(<span class="number">3</span>);</div><div class="line">               e.onComplete();</div><div class="line">           &#125;</div><div class="line">       &#125;).subscribeOn(Schedulers.io());</div><div class="line">       Observable.zip(observable1, observable2, <span class="keyword">new</span> BiFunction&lt;String, Integer, String&gt;() &#123;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> String <span class="title">apply</span><span class="params">(String integer, Integer integer2)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">               <span class="keyword">return</span> integer + integer2;</div><div class="line">           &#125;</div><div class="line">       &#125;).subscribe(<span class="keyword">new</span> Observer&lt;String&gt;() &#123;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSubscribe</span><span class="params">(<span class="comment">/**/</span>Disposable d)</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onSubscribe: "</span>);</div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onNext</span><span class="params">(String string)</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"zip操作结果: "</span> + string);</div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Throwable e)</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onError: "</span>);</div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onComplete</span><span class="params">()</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onComplete: "</span>);</div><div class="line">           &#125;</div><div class="line">       &#125;);</div></pre></td></tr></table></figure>
</li>
<li><p>需要注意的几点内容：</p>
<ol>
<li><p>当两个上游处于同一线程时，他们的发射顺序将会先发送完第一个上游的事件，在发送第二个，而在发送第二个的过程中进行zip，因此，这种情况下的每一个上游的所有事件都会发射。</p>
</li>
<li><p>当两个上游不在同一线程时，他们才是异步的。</p>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/RxJava基础/">RxJava基础</a><a href="/tags/RxJava操作符/">RxJava操作符</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/17/rx-base-operator/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/17/rx-base-operator/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/16/rx-thread-control/" title="RxJava基础篇(二):线程控制" itemprop="url">RxJava基础篇(二):线程控制</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-16T15:03:45.000Z" itemprop="datePublished"> 发表于 2017-02-16</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="orgebbcbd8"></a></p>
<h1 id="当不指定线程的时候，RX遵循线程不变原则。"><a href="#当不指定线程的时候，RX遵循线程不变原则。" class="headerlink" title="当不指定线程的时候，RX遵循线程不变原则。"></a>当不指定线程的时候，RX遵循线程不变原则。</h1><ol>
<li><p>线程不变原则:</p>
<ol>
<li><p>当我们在主线程中创建一个Observable发射事件，则上游默认在主线程发射时间</p>
</li>
<li><p>当我们在主线程中创建一个Observer来接收事件，则下游默认在主线程接收事件</p>
</li>
</ol>
</li>
<li><p>如果需要切换线程，需要使用以下概念：</p>
<ol>
<li>Scheduler：调度器</li>
</ol>
</li>
</ol>
<p><a id="org171cadf"></a></p>
<h1 id="Scheduler："><a href="#Scheduler：" class="headerlink" title="Scheduler："></a>Scheduler：</h1><ol>
<li>相当于线程控制器，Rx通过它来指定每一段代码执行在什么样的线程中。</li>
</ol>
<p><a id="org3ca63ed"></a></p>
<h2 id="内置的几个Scheduler如下："><a href="#内置的几个Scheduler如下：" class="headerlink" title="内置的几个Scheduler如下："></a>内置的几个Scheduler如下：</h2><ol>
<li><p>Scheduler.immediate()：直接在当前线程，这是默认情况（ <strong>仅在RxJava1.0中存在，RxJava2.0中已经删除此API</strong> ）</p>
</li>
<li><p>Scheduler.newThread()：总是启用新线程。</p>
</li>
<li><p>Scheduler.io()：I/O操作（文件读写、数据库读写、网络信息交互等）所使用的Scheduler。</p>
<ol>
<li><p>和newThread差不多。</p>
<ol>
<li><p>区别：</p>
<ol>
<li><p>io()内部实现是用一个没有上限的线程池，可以重用空闲的线程，多数情况下，比newThread()要高效。</p>
</li>
<li><p>建议：不要把计算工作放在这个线程中</p>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li><p>Scheduler.computation()：计算用的Scheduler。</p>
<ol>
<li><p>指的是CPU密集型计算，也就是不会被I/O操作限制性能的操作，如图形计算。</p>
</li>
<li><p>使用固定的线程池，线程数量大小为CPU核数。</p>
</li>
<li><p>同理：I/O操作不要放到这个线程中</p>
</li>
</ol>
</li>
<li><p>AndroidSchedulers.mainThread()：android主线程运行</p>
<ol>
<li><p>android专用的线程，指明在android主线程运行</p>
</li>
<li><p>此API由RxAndroid库中提供，找不到的同学可以检查下是否已经依赖RxAndroid</p>
</li>
</ol>
</li>
</ol>
<p><a id="orgcee2cf9"></a></p>
<h2 id="结合上述的Scheduler，就可以使用下列方法控制线程："><a href="#结合上述的Scheduler，就可以使用下列方法控制线程：" class="headerlink" title="结合上述的Scheduler，就可以使用下列方法控制线程："></a>结合上述的Scheduler，就可以使用下列方法控制线程：</h2><ol>
<li><p>subscribeOn()：指定subscribe()所发生的线程，也就是上游事件发射的线程</p>
<ol>
<li><p>只有第一次指定的时候生效</p>
</li>
<li><p>但是如果上游事件发射的时候我也想要切换线程怎么办？</p>
<ol>
<li><p>doOnsubscribe()</p>
<ol>
<li><p>Subscriber的onSubscribe()方法用于预处理初始化，但是由于onSubscribe()在subscribe()发生的时候就调用了，因此不能指定线程。</p>
</li>
<li><p>那么比如我想在预处理的时候就进行一次UI重绘，必须在主线程执行，这就会导致有线程非法的风险，因为我们不好控制我们当前所在线程</p>
</li>
<li><p>因此，引入doOnSubscribe()方法</p>
</li>
<li><p>doOnsubscribe()可以指定线程。</p>
<ol>
<li><p>默认情况下，它运行在subscribe()发生的线程</p>
</li>
<li><p>而如果在doOnsubscribe()之后有subscribeOn()方法，它将执行在离它最近的subscribeOn()方法指定的线程中。</p>
<ol>
<li>请查看代码如下：<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">Observable.create(onSubscribe)</div><div class="line">    .subscribeOn(Schedulers.io())</div><div class="line">    .doOnSubscribe(<span class="keyword">new</span> Action0() &#123;</div><div class="line">            <span class="meta">@Override</span></div><div class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">call</span><span class="params">()</span> </span>&#123;</div><div class="line">                progressBar.setVisibility(View.VISIBLE); <span class="comment">// 需要在主线程执行</span></div><div class="line">            &#125;</div><div class="line">        &#125;)</div><div class="line">    .subscribeOn(AndroidSchedulers.mainThread())<span class="comment">// 指定主线程，因此doOnsubscribe()方法执行在主线程</span></div><div class="line">    .observeOn(AndroidSchedulers.mainThread())</div><div class="line">    .subscribe(subscriber);</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li><p>observeOn()：指定Subscriber所运行在的线程，也就是下游事件接收的线程</p>
<ol>
<li><p>每进行一次指定，就会切换一次线程</p>
</li>
<li><p>observeOn()方法制定的是Subscriber之后的操作所在的线程，因此如果有多次切换线程的需求，只要在每个想要切换线程的位置调用一次observeOn()就行了</p>
<ol>
<li>伪代码如下：<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">Observable.just(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>) <span class="comment">// IO 线程，由 subscribeOn() 指定</span></div><div class="line">    .subscribeOn(Schedulers.io())</div><div class="line">    .observeOn(Schedulers.newThread())</div><div class="line">    .map(mapOperator) <span class="comment">// 新线程，由 observeOn() 指定</span></div><div class="line">    .observeOn(Schedulers.io())</div><div class="line">    .map(mapOperator2) <span class="comment">// IO 线程，由 observeOn() 指定</span></div><div class="line">    .observeOn(AndroidSchedulers.mainThread) </div><div class="line">    .subscribe(subscriber);  <span class="comment">// Android 主线程，由 observeOn() 指定</span></div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><a id="org9d4808a"></a></p>
<h2 id="标准线程指定代码如下："><a href="#标准线程指定代码如下：" class="headerlink" title="标准线程指定代码如下："></a>标准线程指定代码如下：</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// 创建一个上游的Observable（被观察者）</span></div><div class="line">Observable&lt;String&gt; observable = Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">        <span class="comment">// 发射事件</span></div><div class="line">        Log.d(TAG, <span class="string">"Observable thread is :"</span> + Thread.currentThread().getName());</div><div class="line">        e.onNext(<span class="string">"事件1"</span>);</div><div class="line">        e.onNext(<span class="string">"事件2"</span>);</div><div class="line">        e.onNext(<span class="string">"事件3"</span>);</div><div class="line">        e.onComplete();</div><div class="line">    &#125;</div><div class="line">&#125;);</div><div class="line"><span class="comment">// 创建一个下游Observer（观察者）</span></div><div class="line">Observer&lt;String&gt; observer = <span class="keyword">new</span> Observer&lt;String&gt;() &#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSubscribe</span><span class="params">(<span class="comment">/**/</span>Disposable d)</span> </span>&#123;</div><div class="line">        Log.d(TAG, <span class="string">"onSubscribe: "</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onNext</span><span class="params">(String string)</span> </span>&#123;</div><div class="line">        Log.d(TAG, <span class="string">"onNext: "</span> + string);</div><div class="line">        Log.d(TAG, <span class="string">"Observer thread is :"</span> + Thread.currentThread().getName());</div><div class="line">    &#125;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Throwable e)</span> </span>&#123;</div><div class="line">        Log.d(TAG, <span class="string">"onError: "</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onComplete</span><span class="params">()</span> </span>&#123;</div><div class="line">        Log.d(TAG, <span class="string">"onComplete: "</span>);</div><div class="line">    &#125;</div><div class="line">&#125;;</div><div class="line"><span class="comment">// 上下游建立连接（观察者被观察者建立联系）</span></div><div class="line">observable</div><div class="line">        .subscribeOn(Schedulers.newThread())</div><div class="line">        .observeOn(AndroidSchedulers.mainThread()<span class="comment">/* 指定下游接收事件的Thread */</span>)</div><div class="line">        .subscribe(observer);</div></pre></td></tr></table></figure>
<p><a id="orgc7c6d87"></a></p>
<h1 id="doOnSubscribe-："><a href="#doOnSubscribe-：" class="headerlink" title="doOnSubscribe()："></a>doOnSubscribe()：</h1><ol>
<li><p>Subscriber的onStart()方法用于预处理初始化，但是由于onStart()在subscribe()发生的时候就调用了，因此不能指定线程。</p>
</li>
<li><p>那么比如我想在预处理的时候就进行一次UI重绘，必须在主线程执行，这就会导致有线程非法的风险，因为我们不好控制我们当前所在线程</p>
</li>
<li><p>因此，引入doOnSubscribe()方法</p>
</li>
<li><p>doOnsubscribe()可以指定线程。</p>
<ol>
<li><p>默认情况下，它运行在subscribe()发生的线程</p>
</li>
<li><p>而如果在doOnsubscribe()之后有subscribeOn()方法，它将执行在离它最近的subscribeOn()方法指定的线程中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">Observable.create(onSubscribe)</div><div class="line">    .subscribeOn(Schedulers.io())</div><div class="line">    .doOnSubscribe(<span class="keyword">new</span> Action0() &#123;</div><div class="line">            <span class="meta">@Override</span></div><div class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">call</span><span class="params">()</span> </span>&#123;</div><div class="line">                progressBar.setVisibility(View.VISIBLE); <span class="comment">// 需要在主线程执行</span></div><div class="line">            &#125;</div><div class="line">        &#125;)</div><div class="line">    .subscribeOn(AndroidSchedulers.mainThread())<span class="comment">// 指定主线程，因此doOnsubscribe()方法执行在主线程</span></div><div class="line">    .observeOn(AndroidSchedulers.mainThread())</div><div class="line">    .subscribe(subscriber);</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/RxJava基础/">RxJava基础</a><a href="/tags/观察者模式/">观察者模式</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/16/rx-thread-control/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/16/rx-thread-control/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/16/rx-serials-base-intro/" title="RxJava基础篇(一)" itemprop="url">RxJava基础篇(一)</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-16T08:03:45.000Z" itemprop="datePublished"> 发表于 2017-02-16</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="org6bcab4f"></a></p>
<h1 id="RxJava中有四个概念："><a href="#RxJava中有四个概念：" class="headerlink" title="RxJava中有四个概念："></a>RxJava中有四个概念：</h1><ol>
<li><p>Observable：被观察者</p>
</li>
<li><p>Observer ：观察者</p>
</li>
<li><p>Subscribe：</p>
<ol>
<li><p>订阅：</p>
<ol>
<li>Observable和Observer通过subscribe()方法实现订阅关系，从而Observable可以在需要的时候发出事件来通知Observer(即被观察者通知观察者)</li>
</ol>
</li>
</ol>
</li>
<li><p>事件：由被观察者发出的东西。通常都是一个对象。</p>
</li>
</ol>
<p><a id="org268d805"></a></p>
<h1 id="RxJava与传统观察者模式异同："><a href="#RxJava与传统观察者模式异同：" class="headerlink" title="RxJava与传统观察者模式异同："></a>RxJava与传统观察者模式异同：</h1><ol>
<li><p>多了以下方法：</p>
<ol>
<li><p>onCompleted()：</p>
<ol>
<li>事件队列完结后执行的方法，也就是观察者与被观察者的联系结束以后回调的方法。</li>
</ol>
</li>
<li><p>onError(Throwable e)：事件队列异常的时候执行的方法,当联系发生问题是，进行回调的方法,通常会带上出错的异常信息</p>
</li>
<li><p>上述两个方法中总有一个会被回调，并且两者是互斥的(也就是只有其中一个能够被回调)。</p>
</li>
</ol>
</li>
</ol>
<p><a id="org32066d9"></a></p>
<h1 id="Rx事件模型："><a href="#Rx事件模型：" class="headerlink" title="Rx事件模型："></a>Rx事件模型：</h1><p><a id="orgbec85f8"></a></p>
<h2 id="Rx事件模型图："><a href="#Rx事件模型图：" class="headerlink" title="Rx事件模型图："></a>Rx事件模型图：</h2><blockquote>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/rx-base-1.jpg?watermark/2/text/Unlhbkh1ZW4\=/font/5b6u6L2v6ZuF6buR/fontsize/500/fill/I0JCQkJCQg\=\=/dissolve/100/gravity/SouthWest/dx/10/dy/10" alt="img"></p>
</blockquote>
<p><a id="org0da4ade"></a></p>
<h2 id="首先了解几个概念："><a href="#首先了解几个概念：" class="headerlink" title="首先了解几个概念："></a>首先了解几个概念：</h2><ol>
<li><p>RX事件流：</p>
<ol>
<li>首先RX的整个流程，我们可以看作是一条小河，河水从上游一直不断地往下游流去。</li>
</ol>
</li>
<li><p>上游：</p>
<ol>
<li>被观察者（Observable）</li>
</ol>
</li>
<li><p>下游：</p>
<ol>
<li>观察者（Observer）</li>
</ol>
</li>
<li><p>他们之间的联系：</p>
<ol>
<li><p>他们通过下述方法建立联系.</p>
<pre><code>subscribe()
</code></pre></li>
</ol>
</li>
<li><p>事件的传递：</p>
<ol>
<li>事件就是从上游(被观察者)发出，流到下游（观察者）处，下游（观察者）接收到事件后做出相应的响应的过程。</li>
</ol>
</li>
</ol>
<p><a id="org17d439d"></a></p>
<h1 id="基本使用："><a href="#基本使用：" class="headerlink" title="基本使用："></a>基本使用：</h1><ol>
<li><p>创建上游（被观察者：Observable）</p>
<ol>
<li><p>先看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">Observable&lt;String&gt; observable = Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e<span class="comment">/* 事件发射器 */</span>)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">            <span class="comment">// 发射事件</span></div><div class="line">            e.onNext(<span class="string">"事件1"</span>);</div><div class="line">            e.onNext(<span class="string">"事件2"</span>);</div><div class="line">            e.onNext(<span class="string">"事件3"</span>);</div><div class="line">            e.onComplete();</div><div class="line">        &#125;</div><div class="line">    &#125;);</div></pre></td></tr></table></figure>
</li>
<li><p>概念：</p>
<ol>
<li><p>事件发射器：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">ObservableEmitter    <span class="comment">//事件发射器</span></div></pre></td></tr></table></figure>
</li>
<li><p>顾名思义，事件发射器用于发射事件，可以发射以下三种类型的事件：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">onNext(T value)  <span class="comment">//正常地将某个事件发射出去（T：表示事件的类型）</span></div><div class="line">onComplete()   <span class="comment">//事件流结束后发射一个完成的消息</span></div><div class="line">onError(Throwable e)   <span class="comment">//事件流过程中出现错误发射异常信息</span></div><div class="line"><span class="comment">//显然后面两个方法是上游专门用来通知下游事件流是否成功的</span></div></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>事件发送规则：</p>
<ol>
<li><p>发射事件动作：</p>
<pre><code>onNext()
</code></pre><ol>
<li>可以被上游无限发送、也可以无限接收</li>
</ol>
</li>
<li><p>事件发射完成</p>
<pre><code>onComplete()：
</code></pre><ol>
<li><p>此动作之后，上游可以继续发送事件，但是下游在此之后，将不再继续接收事件</p>
</li>
<li><p>此动作进行多次不造成错误，下游只在第一次响应后不再响应。</p>
</li>
<li><p>上游可以不做此动作(也就是说上游完全可以不告诉下游事件流是否发送完毕)</p>
</li>
</ol>
</li>
<li><p>事件发射过程中出错</p>
<pre><code>onError()：
</code></pre><ol>
<li><p>此动作之后，上游可以继续发送事件，但是下游在此之后，讲不再鸡血接收事件。</p>
</li>
<li><p>此动作进行多次将造成错误，下游接收第二个onError会导致程序崩溃</p>
</li>
<li><p>上游可以不做此动作(也就是说上游完全可以不告诉下游事件流是否发送完毕)</p>
</li>
</ol>
</li>
</ol>
</li>
<li><p>多种创建方式</p>
<ol>
<li><p>单个创建：</p>
<pre><code>create()：
</code></pre><ol>
<li>上述代码已经阐述</li>
</ol>
</li>
<li><p>逐个发射:</p>
<pre><code>just()：
</code></pre><ol>
<li>将传入的参数依次发送出来：<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Observable.just(<span class="string">"事件0"</span>, <span class="string">"事件1"</span>, <span class="string">"事件2"</span>, <span class="string">"事件3"</span>, <span class="string">"事件4"</span>, <span class="string">"事件5"</span>, <span class="string">"事件6"</span>, <span class="string">"事件7"</span>, <span class="string">"事件8"</span>, <span class="string">"事件9"</span>)</div><div class="line">    .subscribe();</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>迭代发射：</p>
<pre><code>fromIterable()：
</code></pre><ol>
<li>将传入的集合中的每一个元素迭代发射<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Observable.fromIterable(Iterable&lt;? extends T&gt; source)</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li><p>创建下游（观察者：Observer）：</p>
<ol>
<li><p>先看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">Observer&lt;String&gt; observer = <span class="keyword">new</span> Observer&lt;String&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSubscribe</span><span class="params">(Disposable d)</span> </span>&#123;</div><div class="line">            Log.d(TAG, <span class="string">"onSubscribe: "</span>);</div><div class="line">        &#125;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onNext</span><span class="params">(String string)</span> </span>&#123;</div><div class="line">            Log.d(TAG, <span class="string">"onNext: "</span> + string);</div><div class="line">        &#125;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Throwable e)</span> </span>&#123;</div><div class="line">            Log.d(TAG, <span class="string">"onError: "</span> + e.getMessage());</div><div class="line">        &#125;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onComplete</span><span class="params">()</span> </span>&#123;</div><div class="line">            Log.d(TAG, <span class="string">"onComplete: "</span>);</div><div class="line">        &#125;</div><div class="line">    &#125;;</div></pre></td></tr></table></figure>
</li>
<li><p>概念:</p>
<ol>
<li><p>订阅回调</p>
<ol>
<li><p>订阅回调指的是下游的on开头的方法都是回调方法，分别对应上游的方法进行回调。</p>
</li>
<li><p>如：</p>
<ol>
<li>上游的onNext()会回调下游的onNext()诸如此类。</li>
</ol>
</li>
</ol>
</li>
<li><p>一次性使用：</p>
<ol>
<li><p>Disposable：</p>
<ol>
<li><p>字面意思是单次使用，用完就销毁了。</p>
</li>
<li><p>我们可以将Disposable理解成拦河大坝。</p>
</li>
<li><p>当调用这个类的dispose()方式时，相当于将上下游的连接切断(相当于在小河上下游之间建起了拦河大坝，所有事件都无法流通到下游了)，此时会导致下游不再接收事件</p>
</li>
<li><p>但是上游将持续发送事件。</p>
</li>
<li><p>请看代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div></pre></td><td class="code"><pre><div class="line">Observable.create(<span class="keyword">new</span> ObservableOnSubscribe&lt;String&gt;() &#123;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(ObservableEmitter&lt;String&gt; e)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">               e.onNext(<span class="string">"事件0"</span>);</div><div class="line">               Log.d(TAG, <span class="string">"onNext0"</span>);</div><div class="line">               e.onNext(<span class="string">"事件1"</span>);</div><div class="line">               Log.d(TAG, <span class="string">"onNext1"</span>);</div><div class="line">               e.onNext(<span class="string">"事件2"</span>);</div><div class="line">               Log.d(TAG, <span class="string">"onNext2"</span>);</div><div class="line">               e.onNext(<span class="string">"事件3"</span>);</div><div class="line">               Log.d(TAG, <span class="string">"onNext3"</span>);</div><div class="line">               e.onNext(<span class="string">"事件4"</span>);</div><div class="line">               Log.d(TAG, <span class="string">"onNext4"</span>);</div><div class="line">               e.onComplete();</div><div class="line">               Log.d(TAG, <span class="string">"onComplete"</span>);</div><div class="line">           &#125;</div><div class="line">       &#125;).subscribe(<span class="keyword">new</span> Observer&lt;String&gt;() &#123;</div><div class="line">           Disposable mDisposable;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onSubscribe</span><span class="params">(Disposable d)</span> </span>&#123;</div><div class="line">               mDisposable = d;  <span class="comment">//将Disposable提升为成员变量，便于在其他地方调用</span></div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onNext</span><span class="params">(String string)</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onNext: "</span> + string);</div><div class="line">               <span class="keyword">if</span> (string.equals(<span class="string">"事件2"</span>)) &#123;</div><div class="line">                   mDisposable.dispose();</div><div class="line">                   Log.d(TAG, <span class="string">"切断水管"</span>);</div><div class="line">               &#125;</div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onError</span><span class="params">(Throwable e)</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onError: "</span>);</div><div class="line">           &#125;</div><div class="line">           <span class="meta">@Override</span></div><div class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onComplete</span><span class="params">()</span> </span>&#123;</div><div class="line">               Log.d(TAG, <span class="string">"onComplete: "</span>);</div><div class="line">           &#125;</div><div class="line">       &#125;);</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>Disposable容器：</p>
<ol>
<li><p>所谓容器就是可以存放Disposable对象的类。我们将Disposable对象存放到容器中就方便对这些拦河大坝统一管理，什么时候开闸发水、蓄水都能够统一到一起。</p>
</li>
<li><p>CompositeDisposable：</p>
<ol>
<li><p>如果有多个Disposable的时候，RxJava内置了容器，当我们得到一个Disposable的时候，加入到容器中：</p>
<pre><code>CompositeDisposable.add()
</code></pre></li>
<li><p>随后，退出的时候，直接使用下述代码就能切断所有联系：</p>
<pre><code>CompositeDisposable.clear()
</code></pre><ol>
<li>清除容器中所有的Disposable随想，同时截断所有河流。</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li><p>实现订阅（Subscribe）</p>
<ol>
<li><p>创建了Observable和Subscriber之后，使用一个方法将两者关联起来就是实现订阅了：</p>
<ol>
<li><p>实现订阅：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">subscribe()： <span class="comment">//实现订阅的API</span></div><div class="line">observable.subscribe(observer);</div></pre></td></tr></table></figure>
<ol>
<li>这个方法的调用，其实看起来像是被观察者订阅了观察者，感觉就像是“杂志订阅了读者”。但是如果不这样写，对流式Api的设计就会造成影响(也就是整个架构就得要重新设计，得不偿失)，因此才这么设计。</li>
</ol>
</li>
</ol>
</li>
<li><p>subscribe()方法的多个重载方法的分析（不完整订阅）：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">final</span> Disposable <span class="title">subscribe</span><span class="params">()</span> </span>&#123;&#125;</div><div class="line"><span class="comment">//不论上游发射什么事件，我都不处理</span></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">final</span> Disposable <span class="title">subscribe</span><span class="params">(Consumer&lt;? <span class="keyword">super</span> T&gt; onNext)</span></span></div><div class="line"><span class="comment">//只处理上游发射过来的onNext()事件</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">final</span> Disposable <span class="title">subscribe</span><span class="params">(Consumer&lt;? <span class="keyword">super</span> T&gt; onNext, Consumer&lt;? <span class="keyword">super</span> Throwable&gt; onError)</span></div><div class="line"><span class="comment">//只处理上游发射过来的onNext()、onError()事件</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">final</span> Disposable <span class="title">subscribe</span><span class="params">(Consumer&lt;? <span class="keyword">super</span> T&gt; onNext, Consumer&lt;? <span class="keyword">super</span> Throwable&gt; onError, Action onComplete)</span></div><div class="line"><span class="comment">//只处理上游发射过来的onNext()、onError()、onComplete()事件</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">final</span> Disposable <span class="title">subscribe</span><span class="params">(Consumer&lt;? <span class="keyword">super</span> T&gt; onNext, Consumer&lt;? <span class="keyword">super</span> Throwable&gt; onError, Action onComplete, Consumer&lt;? <span class="keyword">super</span> Disposable&gt; onSubscribe)</span></div><div class="line"><span class="comment">//只处理上游发射过来的onNext()、onError()、onComplete()、onSubscribe事件</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title">subscribe</span><span class="params">(Observer&lt;? <span class="keyword">super</span> T&gt; observer)</span></div><div class="line"><span class="comment">//完整订阅</span></div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/RxJava基础/">RxJava基础</a><a href="/tags/观察者模式/">观察者模式</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/16/rx-serials-base-intro/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/16/rx-serials-base-intro/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/15/rx-serials-respon-explain/" title="什么是响应式编程" itemprop="url">什么是响应式编程</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-15T12:10:32.000Z" itemprop="datePublished"> 发表于 2017-02-15</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="org5488664"></a></p>
<h1 id="什么是响应式编程？"><a href="#什么是响应式编程？" class="headerlink" title="什么是响应式编程？"></a>什么是响应式编程？</h1><ol>
<li><p>请看下列代码：</p>
  <figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> a = <span class="number">4</span>;</div><div class="line"><span class="keyword">int</span> b = <span class="number">5</span>;</div><div class="line"><span class="keyword">int</span> c = a + b;</div><div class="line">System.out.println(c); <span class="comment">// 9</span></div><div class="line">a = <span class="number">6</span>;</div><div class="line">System.out.println(c);</div><div class="line"><span class="comment">// 9 again, but if 'c' was tracking the changes of 'a' and 'b',</span></div><div class="line"><span class="comment">// it would've been 6 + 5 = 11</span></div></pre></td></tr></table></figure>
</li>
<li><p>上述代码中，当我们改变“a”和“b”的值的时候，“c”并没有发生改变。换句话说，“a”和“b”的改变并没有影响到“c“。</p>
<ol>
<li>这就是命令式编程环境：程序以流的形式，传递数据的改变</li>
</ol>
</li>
<li><p>而响应式编程中，”c“的值会随着”a“或者”b“的更新而更新</p>
</li>
</ol>
<p><a id="org846ab57"></a></p>
<h1 id="为什么需要响应式编程："><a href="#为什么需要响应式编程：" class="headerlink" title="为什么需要响应式编程："></a>为什么需要响应式编程：</h1><ol>
<li><p>避免回调地狱：</p>
<ol>
<li><p>请看如下代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">new</span> Thread() &#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.run();</div><div class="line">        <span class="keyword">for</span> (File folder : folders) &#123;</div><div class="line">            File[] files = folder.listFiles();</div><div class="line">            <span class="keyword">for</span> (File file : files) &#123;</div><div class="line">                <span class="keyword">if</span> (file.getName().endsWith(<span class="string">".png"</span>)) &#123;</div><div class="line">                    <span class="keyword">final</span> Bitmap bitmap = getBitmapFromFile(file);</div><div class="line">                    getActivity().runOnUiThread(<span class="keyword">new</span> Runnable() &#123;</div><div class="line">                            <span class="meta">@Override</span></div><div class="line">                            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</div><div class="line">                                imageCollectorView.addImage(bitmap);</div><div class="line">                            &#125;</div><div class="line">                        &#125;);</div><div class="line">                &#125;</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;.start();</div></pre></td></tr></table></figure>
<ol>
<li>这样的代码写法，首先外循环的结束需要内循环的支持，而我们看到的ImageCollectorView设置图片，必须是在循环匹配的时候进行。说明我们在显示View的时候，会是一张一张展示出来，这样与我们写程序经常讲究的回调和异步就相背离了。</li>
</ol>
</li>
<li><p>再看以下代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//The "Nested Callbacks" Way</span></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">fetchUserDetails</span><span class="params">()</span> </span>&#123;</div><div class="line">    <span class="comment">//first, request the users...</span></div><div class="line">    mService.requestUsers(<span class="keyword">new</span> Callback&lt;GithubUsersResponse&gt;() &#123;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">success</span><span class="params">(<span class="keyword">final</span> GithubUsersResponse githubUsersResponse,</span></span></div><div class="line">                            <span class="keyword">final</span> Response response) &#123;</div><div class="line">            Timber.i(TAG, <span class="string">"Request Users request completed"</span>);</div><div class="line">            <span class="keyword">final</span> <span class="keyword">synchronized</span> List&lt;GithubUserDetail&gt; githubUserDetails</div><div class="line">                                              = <span class="keyword">new</span> ArrayList&lt;GithubUserDetail&gt;();</div><div class="line">            <span class="comment">//next, loop over each item in the response</span></div><div class="line">            <span class="keyword">for</span> (GithubUserDetail githubUserDetail : githubUsersResponse) &#123;</div><div class="line">                <span class="comment">//request a detail object for that user</span></div><div class="line">                mService.requestUserDetails(githubUserDetail.mLogin,</div><div class="line">                                            <span class="keyword">new</span> Callback&lt;GithubUserDetail&gt;() &#123;</div><div class="line">                    <span class="meta">@Override</span></div><div class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">success</span><span class="params">(GithubUserDetail githubUserDetail,</span></span></div><div class="line">                                        Response response) &#123;</div><div class="line">                        Log.i(<span class="string">"User Detail request completed for user : "</span> </div><div class="line">                                                        + githubUserDetail.mLogin);</div><div class="line">                        githubUserDetails.add(githubUserDetail);</div><div class="line">                        <span class="keyword">if</span> (githubUserDetails.size() == githubUsersResponse.mGithubUsers.size()) &#123;</div><div class="line">                            <span class="comment">//we've downloaded'em all - notify all who are interested!</span></div><div class="line">                            mBus.post(<span class="keyword">new</span> UserDetailsLoadedCompleteEvent(githubUserDetails));</div><div class="line">                        &#125;</div><div class="line">                    &#125;</div><div class="line">                    <span class="meta">@Override</span></div><div class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">failure</span><span class="params">(RetrofitError error)</span> </span>&#123;</div><div class="line">                        Log.e(TAG, <span class="string">"Request User Detail Failed!!!!"</span>, error);</div><div class="line">                    &#125;</div><div class="line">                &#125;);</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">        <span class="meta">@Override</span></div><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">failure</span><span class="params">(RetrofitError error)</span> </span>&#123;</div><div class="line">            Log.e(TAG, <span class="string">"Request User Failed!!!!"</span>, error);</div><div class="line">        &#125;</div><div class="line">    &#125;);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ol>
<li><p>上述代码中，我们首先调用web service，使用回调接口将成功的结果传递给下一个web service请求，同时定义另一个成功回调，然后发起下一个web service请求。这其中有两层回调，同时也是异步的。和我们推崇的代码风格比较接近了。但是你们看出来问题了吗？</p>
<ol>
<li>尽管上述代码用了回调。是异步请求，每个请求完成的时候不会阻塞。但是代码的易读性？可维护性呢？</li>
</ol>
</li>
</ol>
</li>
<li><p>最后，这是RxJava的代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">rxFetchUserDetails</span><span class="params">()</span> </span>&#123;</div><div class="line">    <span class="comment">//request the users</span></div><div class="line">    mService.rxRequestUsers().concatMap(Observable::from)</div><div class="line">        .concatMap((GithubUser githubUser) -&gt;</div><div class="line">                   <span class="comment">//request the details for each user</span></div><div class="line">                   mService.rxRequestUserDetails(githubUser.mLogin)</div><div class="line">                   )</div><div class="line">        <span class="comment">//accumulate them as a list</span></div><div class="line">        .toList()</div><div class="line">        <span class="comment">//define which threads information will be passed on</span></div><div class="line">        .subscribeOn(Schedulers.newThread())</div><div class="line">        .observeOn(AndroidSchedulers.mainThread())</div><div class="line">        <span class="comment">//post them on an eventbus</span></div><div class="line">        .subscribe(githubUserDetails -&gt; &#123;</div><div class="line">                EventBus.getDefault().post(<span class="keyword">new</span> UserDetailsLoadedCompleteEvent(githubUserDetails));</div><div class="line">            &#125;);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ol>
<li><p>抛弃回调，代码精简，可读性非常高，流式API，让人一目了然。</p>
</li>
<li><p>这就是响应式编程，流式API的好处</p>
</li>
</ol>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/响应式编程/">响应式编程</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/15/rx-serials-respon-explain/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/15/rx-serials-respon-explain/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/15/spacemacs_install_config/" title="Spacemacs的安装与配置（基础篇）" itemprop="url">Spacemacs的安装与配置（基础篇）</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-15T09:40:37.000Z" itemprop="datePublished"> 发表于 2017-02-15</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="orgfa88029"></a></p>
<h1 id="下载："><a href="#下载：" class="headerlink" title="下载："></a>下载：</h1><ol>
<li><p>找到spacemacs的地址 ：</p>
<ol>
<li><p>spacemacs的github地址：<a href="https://github.com/syl20bnr/spacemacs#documentation" target="_blank" rel="external">https://github.com/syl20bnr/spacemacs#documentation</a></p>
</li>
<li><p>建议使用master分之进行配置。</p>
</li>
<li><p>克隆spacemacs替代原有的.emacs.d目录</p>
</li>
</ol>
</li>
</ol>
<p><a id="org7521f0d"></a></p>
<h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><ol>
<li><p>直接使用emacs命令就可以打开spacemacs。</p>
</li>
<li><p>安装时会提问使用哪种编辑模式,补全模式等：</p>
<blockquote>
<p>我使用的是下表中的配置:</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">编辑模式</th>
<th scope="col" class="org-left">补全模式</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">vim</td>
<td class="org-left">auto-completion</td>
</tr>
</tbody>
</table>
</blockquote>
</li>
<li><p>打开emacs，开始安装配置spacemacs。</p>
<ol>
<li><p>由于spacemacs也是使用elpa源，因此如果使用国外官网，会比较慢，建议替换成使用国内的镜像源。</p>
<ol>
<li><p>在～目录下，找到.spacemacs文件，打开以后定位以下方法：</p>
<pre><code>user-init()
</code></pre></li>
<li><p>在这个方法的方法体内修改使用的源,代码如下</p>
<pre><code>(setq configuration-layer--elpa-archives
      &apos;((&quot;melpa-cn&quot; . &quot;http://elpa.emacs-china.org/melpa/&quot;)
        (&quot;org-cn&quot;   . &quot;http://elpa.emacs-china.org/org/&quot;)
        (&quot;gnu-cn&quot;   . &quot;http://elpa.emacs-china.org/gnu/&quot;)))
)
</code></pre></li>
<li><p>可以在前面“安装”步骤进行时，等到~/.spacemacs文件生成以后再对其修改，否则可能找不到这个文件,因为这个文件是在安装过程中生成的。</p>
</li>
</ol>
</li>
</ol>
</li>
<li><p>修改好安装源以后，重新打开spacemacs。安装完成以后会显示欢迎界面，就可以使用了</p>
</li>
<li><p>配置layer的启用</p>
</li>
</ol>
<p><a id="org95257ea"></a></p>
<h1 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h1><p><a id="org970c1b7"></a></p>
<h2 id="启用关闭Layer"><a href="#启用关闭Layer" class="headerlink" title="启用关闭Layer"></a>启用关闭Layer</h2><ol>
<li><p>找到以下代码位置</p>
<pre><code>dotspacemacs-configuration-layers
</code></pre></li>
<li><p>在这个方法的配置中，有一些默认自带的layer，我们只需要取消注释，进行安装就可以启用了。可以启用的如下：</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">layer名称</th>
<th scope="col" class="org-left">描述信息</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">ivy</td>
<td class="org-left">swiper搜索插件</td>
</tr>


<tr>
<td class="org-left">auto-completion</td>
<td class="org-left">自动补全</td>
</tr>


<tr>
<td class="org-left">better-defaults</td>
<td class="org-left">更好的使用spacemacs，如增加C-a,C-e为跳转到非空行首行尾</td>
</tr>


<tr>
<td class="org-left">emacs-lisp</td>
<td class="org-left">官方默认启用</td>
</tr>


<tr>
<td class="org-left">markdown</td>
<td class="org-left">markdown的layer</td>
</tr>


<tr>
<td class="org-left">org</td>
<td class="org-left">org-mode的layer</td>
</tr>


<tr>
<td class="org-left">spell-checking</td>
<td class="org-left">拼写检查</td>
</tr>


<tr>
<td class="org-left">syntax-checking</td>
<td class="org-left">语法检查</td>
</tr>
</tbody>
</table>
</blockquote>
</li>
<li><p>启用以后，可以执行以下命令刷新package，而不需要重启emacs（当然重启也是没有问题的）</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">快捷键</th>
<th scope="col" class="org-left">作用</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">SPC-f-e-R</td>
<td class="org-left">刷新layer，没有安装的会自动进行安装</td>
</tr>
</tbody>
</table>


</blockquote>
</li>
</ol>
<p><a id="org29db8c8"></a></p>
<h2 id="git管理spacemacs配置"><a href="#git管理spacemacs配置" class="headerlink" title="git管理spacemacs配置"></a>git管理spacemacs配置</h2><ol>
<li><p>将自己的spacemacs配置添加到git仓库进行管理</p>
<ol>
<li><p>新建目录：</p>
<pre><code>~/.spacemacs.d
</code></pre></li>
<li><p>复制.spacemacs文件到上述目录中，修改名称为init.el</p>
</li>
</ol>
</li>
</ol>
<p><a id="orge4641cd"></a></p>
<h2 id="优化evil配置："><a href="#优化evil配置：" class="headerlink" title="优化evil配置："></a>优化evil配置：</h2><ol>
<li><p>找到以下代码位置：</p>
<pre><code>(defun dotspacemacs/user-config ()
</code></pre></li>
<li><p>添加以下代码到上述方法中：</p>
<pre><code>(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map [escape] &apos;evil-normal-state)
</code></pre></li>
</ol>
<p><a id="org9b607d3"></a></p>
<h2 id="配置customize-group功能修改的属性存放的位置"><a href="#配置customize-group功能修改的属性存放的位置" class="headerlink" title="配置customize-group功能修改的属性存放的位置"></a>配置customize-group功能修改的属性存放的位置</h2><ol>
<li><p>通常我们希望将customize-group功能修改的这些属性存放到custom.el中，方便我们随时查看，管理。</p>
</li>
<li><p>因此，在.spacemacs.d/.init.el结尾处加入以下代码：</p>
<pre><code>(setq custom-file (expand-file-name &quot;custom.el&quot; dotspacemacs-directory))
(load custom-file &apos;no-error &apos;no-message)
</code></pre></li>
</ol>
<p><a id="org4985763"></a></p>
<h2 id="修改主题："><a href="#修改主题：" class="headerlink" title="修改主题："></a>修改主题：</h2><ol>
<li><p>找到以下代码位置：</p>
<pre><code>dotspacemacs-themes &apos;(
</code></pre></li>
<li><p>需要什么主题，在其中加入即可，第一行的主题会优先被加载。如下：</p>
<pre><code>dotspacemacs-themes &apos;(solarized-dark
                      monokai
                      spacemacs-dark
                      spacemacs-light
                      solarized-light
                      leuven
                      zenburn)
</code></pre></li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/Emacs系列/">Emacs系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/Spacemacs/">Spacemacs</a><a href="/tags/Emacs/">Emacs</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/15/spacemacs_install_config/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/15/spacemacs_install_config/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/15/org-mode-grammar/" title="Org-mode语法基础" itemprop="url">Org-mode语法基础</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-15T05:20:07.000Z" itemprop="datePublished"> 发表于 2017-02-15</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="orgc54cd67"></a></p>
<h1 id="标题菜单："><a href="#标题菜单：" class="headerlink" title="标题菜单："></a>标题菜单：</h1><p><a id="org7b4faa1"></a></p>
<h2 id="无序列表："><a href="#无序列表：" class="headerlink" title="无序列表："></a>无序列表：</h2><ol>
<li><p>使用“*”作为开头，数量越多表示标题等级越低</p>
</li>
<li><p>标题不可伸缩，其内部内容可以进行伸缩</p>
</li>
<li><p>标题最多10个等级</p>
<pre><code>* org-mode
** 大纲
正在编写大纲
** 轻量级标记语言
* 可以导出其他格式
支持html，pdf等格式
</code></pre></li>
</ol>
<p><a id="orgf256110"></a></p>
<h2 id="有序列表："><a href="#有序列表：" class="headerlink" title="有序列表："></a>有序列表：</h2><ol>
<li><p>有序列表项以‘1.’、‘1)’或者开头。</p>
</li>
<li><p>同一列表中的项的第一行必须缩进相同程度。当下一行的缩进与列表项的的开头的符号或者数字相同或者更小时，这一项就结束了。当所有的项都关上时，或者后面有两个空行时，列表就结束了。</p>
<pre><code>** Lord of the Rings
My favorite scenes are (in this order)
1. The attack of the Rohirrim
2. Eowyn&apos;s fight with the witch king
+ this was already my favorite scene in the book
我是+列表项中的一员
+ I really like Miranda Otto.
3. seioiawefoji
我是3.列表项中的一员
3) aweofijea
awaeoifj
awefoai

因为中间隔了两行，所以3)不包括我
Important actors in this film are:
- Elijah Wood :: He plays Frodo
- Sean Austin :: He plays Sam, Frodo&apos;s friend.
</code></pre></li>
</ol>
<p><a id="org20c73cb"></a></p>
<h2 id="快捷键："><a href="#快捷键：" class="headerlink" title="快捷键："></a>快捷键：</h2><ol>
<li><p>折叠大纲</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">快捷键</td>
<td class="org-left">命令</td>
<td class="org-left">说明</td>
</tr>


<tr>
<td class="org-left">S-TAB</td>
<td class="org-left">org-shifttab</td>
<td class="org-left">循环切换整个文档的大纲状态（三种状态：折叠，打开下一级，打开全部）</td>
</tr>


<tr>
<td class="org-left">TAB</td>
<td class="org-left">org-cycle</td>
<td class="org-left">循环切换光标所在大纲的状态</td>
</tr>
</tbody>
</table>
</blockquote>
</li>
<li><p>在大纲之间移动</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">快捷键</td>
<td class="org-left">命令</td>
<td class="org-left">说明</td>
</tr>


<tr>
<td class="org-left">C-c C-n/p</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">下/上一标题</td>
</tr>


<tr>
<td class="org-left">C-c C-f/b</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">下/上一标题（仅限同级标题）</td>
</tr>


<tr>
<td class="org-left">C-c C-u</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">跳到上一级标题</td>
</tr>


<tr>
<td class="org-left">C-c C-j</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">切换到大纲浏览状态</td>
</tr>
</tbody>
</table>
</blockquote>
</li>
<li><p>基于大纲的编辑</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">

<col class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">快捷键</th>
<th scope="col" class="org-left">命令</th>
<th scope="col" class="org-left">说明</th>
</tr>


<tr>
<th scope="col" class="org-left">M-RET</th>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-left">插入一个同级标题</th>
</tr>


<tr>
<th scope="col" class="org-left">M-S-RET</th>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-left">插入一个同级TODO标题</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">M-LEFT/RIGHT</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将当前标题升/降级（包括子树）</td>
</tr>


<tr>
<td class="org-left">M-UP/DOWN</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将当前标题上/下移（包括子树）</td>
</tr>


<tr>
<td class="org-left">M-S-LEFT/RIGHT</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将当前升/降级（不包括子树）</td>
</tr>


<tr>
<td class="org-left">M-S-UP/DOWN</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将当前上/下移（不包括子树）</td>
</tr>
</tbody>

<tbody>
<tr>
<td class="org-left">C-c *</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将本行设为标题/正文</td>
</tr>


<tr>
<td class="org-left">C-c C-w</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">将子树或区域移动到另一标题处（跨文件）</td>
</tr>


<tr>
<td class="org-left">C-x n s/w</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">只显示当前子树/返回</td>
</tr>


<tr>
<td class="org-left">C-c /</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">只列出包含搜索结果的大纲，并高亮，支持多种搜索方式</td>
</tr>


<tr>
<td class="org-left">C-c C-c</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">取消高亮</td>
</tr>
</tbody>
</table>


</blockquote>
</li>
</ol>
<p><a id="orgc6ce9ef"></a></p>
<h1 id="内容编辑："><a href="#内容编辑：" class="headerlink" title="内容编辑："></a>内容编辑：</h1><ol>
<li><p>粗体：</p>
<pre><code>*粗体* 用两个星号包裹，星号与粗体前后的其他字应该各有至少一个空格或英文标点分隔开来
*bold*,word,用英文逗号分隔开，bold显示出粗体效果
*bold*word则不显示粗体效果
</code></pre></li>
<li><p>斜体：</p>
<pre><code>/hello/ 用&quot;/&quot;包裹，规则同粗体
/斜体/ 好像对中文不管用?导出成HTML时看到还是生效了，可能是字体关系吧
</code></pre></li>
<li><p>下划线：</p>
<pre><code>_下划线_ 用&quot;_&quot;在前后包裹，规则同粗体
_下划线_紧跟其他字，则不生效
</code></pre></li>
<li><p>删除线：</p>
<pre><code>+删除线+ 用&quot;+&quot;在前后包裹，规则同粗体
</code></pre></li>
<li><p>代码块：</p>
<ol>
<li><p>加入elisp代码块：</p>
<pre><code>#+BEGIN_SRC emacs-lisp
    在这里添加你的elisp代码
#+END_SRC
</code></pre></li>
<li><p>编辑代码</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">C-c ‘</td>
<td class="org-left">把代码块中的内容新开一个buffer进行编辑</td>
</tr>
</tbody>
</table>

</blockquote>
<ol>
<li>再按一次完成编辑</li>
</ol>
</li>
</ol>
</li>
<li><p>引用块：</p>
<pre><code>#+BEGIN_QUOTE
引用内容
#+END_QUOTE
</code></pre></li>
<li><p>示例块：</p>
<pre><code>#+Begin_EXAMPLE
示例
#+END_EXAMPLE
</code></pre></li>
</ol>
<p><a id="org24744a6"></a></p>
<h1 id="表格："><a href="#表格：" class="headerlink" title="表格："></a>表格：</h1><ol>
<li><p>代码实例：</p>
<pre><code>| Name| Phone | Age |
|-------|------|-----|
| Peter | 1234 | 17  |
| Anna  | 4321 | 25  |
</code></pre></li>
<li><p>分隔符：“|”    表格中使用“&vert;”进行转义</p>
<ol>
<li><p>使用：</p>
<ol>
<li><p>表格创建:</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">C-c &vert;</td>
<td class="org-left">创建表格，输入5x5（根据选中或者活动区域内容）创建5行5列表格</td>
</tr>


<tr>
<td class="org-left">&vert;&vert;&vert;&vert; C-c RET</td>
<td class="org-left">创建一个带分割线的表格，竖线中间填写表头，不填写的话就是空表头</td>
</tr>
</tbody>
</table>


</blockquote>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><a id="orga843529"></a></p>
<h1 id="记录日常安排："><a href="#记录日常安排：" class="headerlink" title="记录日常安排："></a>记录日常安排：</h1><ol>
<li><p>使用此项功能能够编写日程列表：</p>
<blockquote>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col class="org-left">

<col class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left">C-c C-s：</td>
<td class="org-left">为一个item设置Schedule时间</td>
</tr>


<tr>
<td class="org-left">C-c C-d：</td>
<td class="org-left">为一个item设置Deadline时间</td>
</tr>
</tbody>
</table>


</blockquote>
</li>
</ol>
<p><a id="org67ba7fb"></a></p>
<h1 id="org-mode文学编程"><a href="#org-mode文学编程" class="headerlink" title="org-mode文学编程"></a>org-mode文学编程</h1><ol>
<li><p>可以结合org-mode和emacs，将所有的init.el文件写入到org中来。只要将所有elisp写到org的代码注释块中，就能在emacs中生效。</p>
</li>
<li><p>配置：</p>
<pre><code>(require &apos;org-install)
(require &apos;ob-tangle)
(org-babel-load-file (expand-file-name &quot;org-file-name.org&quot; user-emacs-directory))
</code></pre></li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/Emacs系列/">Emacs系列</a>►<a class="article-category-link" href="/categories/Emacs系列/org-mode/">org-mode</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/Spacemacs/">Spacemacs</a><a href="/tags/Emacs/">Emacs</a><a href="/tags/org/">org</a><a href="/tags/org-mode/">org-mode</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/15/org-mode-grammar/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/15/org-mode-grammar/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/14/rx-serials-respon-observer/" title="观察者模式详解" itemprop="url">观察者模式详解</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-14T06:01:45.000Z" itemprop="datePublished"> 发表于 2017-02-14</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="org2eb4f0d"></a></p>
<h1 id="概念："><a href="#概念：" class="headerlink" title="概念："></a>概念：</h1><ol>
<li><p>建立一种对象与对象之间的联系,一个对象发生改变的时候自动通知其他对象做出反应.</p>
<ol>
<li><p>观察目标:发生改变的对象(可以对应多个观察者,多个观察者之间没有联系,同时可根据需要增删观察者)</p>
</li>
<li><p>观察者:被通知的对象</p>
</li>
</ol>
</li>
</ol>
<p><a id="orgc95f9e8"></a></p>
<h1 id="名词"><a href="#名词" class="headerlink" title="名词:"></a>名词:</h1><ol>
<li><p>Subject：目标</p>
<ol>
<li>Subject把所有对观察者对象的引用保存在一个聚集（比如ArrayList对象）中，每个Subject都可以有任何数量的观察者。Subject提供一个接口，可以增加和删除观察者对象，Subject又叫做被观察者（Obserbable）</li>
</ol>
</li>
<li><p>ConcreteSubject：具体目标</p>
<ol>
<li>将有关状态存入ConcreteSubject；在ConcreteSubject的内部状态改变时，给所有登记过的观察者发送通知。ConcreteSubject又叫做具体被观察者（Concrete Observable）</li>
</ol>
</li>
<li><p>Observer：观察者</p>
<ol>
<li>为所有的ConcreteObserver定义一个接口，在得到Subject的通知时更新自己，这个接口叫做更新接口</li>
</ol>
</li>
<li><p>ConcreteObserver：具体观察者</p>
<ol>
<li>存储与Subject的状态自恰的状态。ConcreteObserver实现Observer所要求的更新接口，以便使本身的状态与Subject的状态相互协调。如果需要，ConcreteObserver可以保持一个指向ConcreteSubject的引用</li>
</ol>
</li>
</ol>
<p><a id="org2068f16"></a></p>
<h1 id="实现："><a href="#实现：" class="headerlink" title="实现："></a>实现：</h1><ol>
<li><p>观察者模式使用Subject、Observer和Client三个类。</p>
<ol>
<li><p>Subject：</p>
<ol>
<li><p>带有绑定观察者到Client的方法</p>
</li>
<li><p>带有从Client解绑观察者的方法</p>
</li>
</ol>
</li>
</ol>
</li>
<li><p>实例：</p>
<ol>
<li><p>首先创建Subjcet：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Subject</span> </span>&#123;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 用来保存注册的观察者对象</div><div class="line">     */</div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> List&lt;Observer&gt; OBSERVERS_LIST = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 注册观察者对象</div><div class="line">     * </div><div class="line">     * <span class="doctag">@param</span> observer 观察者对象</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">attach</span><span class="params">(Observer observer)</span> </span>&#123;</div><div class="line">        OBSERVERS_LIST.add(observer);</div><div class="line">    &#125;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 删除观察者对象</div><div class="line">     * </div><div class="line">     * <span class="doctag">@param</span> observer 观察者对象</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">dettach</span><span class="params">(Observer observer)</span> </span>&#123;</div><div class="line">        OBSERVERS_LIST.remove(observer);</div><div class="line">    &#125;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 通知所有注册的观察者对象</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">notifyAllObservers</span><span class="params">(<span class="keyword">int</span> progress)</span> </span>&#123;</div><div class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; OBSERVERS_LIST.size(); i++) &#123;</div><div class="line">            Observer observer = OBSERVERS_LIST.get(i);</div><div class="line">            observer.updateProgress(progress);</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>创建Observer类：</p>
<ol>
<li>Obeserver可以是一个接口，只需要有一个用于回调的方法就可以了<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Observer</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">void</span> <span class="title">updateProgress</span><span class="params">(<span class="keyword">int</span> progress)</span></span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>创建ConcreteSubject的实例：</p>
<ol>
<li>下载进程，它只负责下载，View的显示交给观察者进行更新，它负责通知观察者目前下载进度就行<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DownLoadingComponent</span> <span class="keyword">extends</span> <span class="title">Subject</span> <span class="keyword">implements</span> <span class="title">Runnable</span> </span>&#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++) &#123;</div><div class="line">            SystemClock.sleep(<span class="number">300</span>);</div><div class="line">            progressChange(i);</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">private</span> <span class="keyword">int</span> progress;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 模拟正在下载，进度正在更新</div><div class="line">     *</div><div class="line">     * <span class="doctag">@param</span> progress</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">progressChange</span><span class="params">(<span class="keyword">int</span> progress)</span> </span>&#123;</div><div class="line">        <span class="keyword">this</span>.progress = progress;</div><div class="line">        System.out.println(<span class="string">"后台下载进度"</span> + progress);</div><div class="line">        notifyAllObservers(progress);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>创建ConcreteObserver实例：</p>
<ol>
<li><p>前台显示progress的页面</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> <span class="keyword">implements</span> <span class="title">Observer</span></span>&#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">updateProgress</span><span class="params">(<span class="keyword">int</span> progress)</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"我是MainActivity,在更新进度"</span> + progress);</div><div class="line">        mProgressView.setProgress(progress);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>被遮挡但是能够看到进度条的页面</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DetailDialogActivity</span> <span class="keyword">extends</span> <span class="title">Activity</span> <span class="keyword">implements</span> <span class="title">Observer</span> </span>&#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">updateProgress</span><span class="params">(<span class="keyword">int</span> progress)</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"我是DialogActivity，在更新进度"</span> + progress);</div><div class="line">        mProgressView.setProgress(progress);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><a id="org1c6eab2"></a></p>
<h1 id="Demo实例："><a href="#Demo实例：" class="headerlink" title="Demo实例："></a>Demo实例：</h1><p><img src="" alt="img"></p>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/观察者模式/">观察者模式</a><a href="/tags/设计模式/">设计模式</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/14/rx-serials-respon-observer/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/14/rx-serials-respon-observer/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/14/JavaCallBack/" title="JavaCallBack" itemprop="url">JavaCallBack</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-14T01:15:32.000Z" itemprop="datePublished"> 发表于 2017-02-14</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="org1d6bfd5"></a></p>
<h1 id="Java回调机制详解："><a href="#Java回调机制详解：" class="headerlink" title="Java回调机制详解："></a>Java回调机制详解：</h1><p><a id="org0e494e8"></a></p>
<h2 id="回调方法："><a href="#回调方法：" class="headerlink" title="回调方法："></a>回调方法：</h2><ul>
<li>程序员A写了一段程序（a1），其中预留了一个回调函数的接口，并且封装好了这个接口。程序员B要让a1调用自己的程序b1中的某个方法，于是他通过a1中的接口回调自己b1中的方法。达到目的<ul>
<li><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/java-callback-0.png-RyanHuenBlog" alt="img"></li>
</ul>
</li>
<li>WTF,你到底在说什么？？？？？</li>
</ul>
<p><a id="org8c3c789"></a></p>
<h2 id="概念看不懂？不够生动-好的，我们来掰扯掰扯："><a href="#概念看不懂？不够生动-好的，我们来掰扯掰扯：" class="headerlink" title="概念看不懂？不够生动?好的，我们来掰扯掰扯："></a>概念看不懂？不够生动?好的，我们来掰扯掰扯：</h2><p><a id="org7082b20"></a></p>
<h3 id="煮一个比较实际的栗子："><a href="#煮一个比较实际的栗子：" class="headerlink" title="煮一个比较实际的栗子："></a>煮一个比较实际的栗子：</h3><ol>
<li><p>人养了一只宠物狗，有一天，人被女神放鸽子了，人很生气，调用了自己的方法，揍了一顿他的狗。他的狗被揍了，也很生气，于是反咬了人一口，人感觉非常疼啊，于是他喊了一声。</p>
</li>
<li><p>在上面的栗子中，我们能够看到回调的模型。</p>
</li>
</ol>
<p><a id="org82d5c38"></a></p>
<h3 id="首先："><a href="#首先：" class="headerlink" title="首先："></a>首先：</h3><ol>
<li><p>人揍了狗，狗反咬人，人感觉疼就喊了。这就是一个回调。</p>
</li>
<li><p>疑问：</p>
<ol>
<li>怎么能够触发狗一咬人，人就喊疼呢？</li>
</ol>
</li>
<li><p>这就需要回调的知识了</p>
<ol>
<li><p>首先我们来画个图：</p>
<p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/java-callback-1.png-RyanHuenBlog" alt="img"></p>
</li>
<li><p>代码实例：</p>
<ol>
<li><p>首先需要一个回调接口：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//回调接口，定义人被咬了以后的行为的接口,接口中的方法描述人被咬了以后的行为</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CallBack</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">callBack</span><span class="params">()</span></span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>其次我们需要一条狗：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Dog</span> </span>&#123;</div><div class="line">    <span class="comment">//实际上，所谓回调，不是真的让Dog去通知人喊疼。这是不合逻辑的</span></div><div class="line">    <span class="comment">//所以应该是Dog内部有一个回调接口的对象，这个对象去通知人喊疼。</span></div><div class="line">    <span class="comment">//而这个对象，是通过Dog进行赋值的，它的来源就是Person，因为Person实现了这个回调接口</span></div><div class="line">    CallBack mCallBack;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setCallBack</span><span class="params">(CallBack callBack)</span> </span>&#123;</div><div class="line">        mCallBack = callBack;</div><div class="line">    &#125;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">bitePerson</span><span class="params">()</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"狗反咬一口"</span>);</div><div class="line">        mCallBack.callBack();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>现在还需要有一个人</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//人实现回调接口，就可以定义被咬以后的行为了</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> <span class="keyword">implements</span> <span class="title">CallBack</span> </span>&#123;</div><div class="line">    <span class="comment">//同时需要在人内部封装一个狗对象</span></div><div class="line">    Dog mDog;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Person</span><span class="params">(Dog dog)</span> </span>&#123;</div><div class="line">        mDog = dog;</div><div class="line">        <span class="comment">//给狗内部的回调接口对象赋值</span></div><div class="line">        mDog.setCallBack(<span class="keyword">this</span>);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="comment">//人揍狗的方法</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">hitDog</span><span class="params">()</span></span>&#123;</div><div class="line">        System.out.println(<span class="string">"人不高兴，揍了狗"</span>);</div><div class="line">        mDog.bitePerson();</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="comment">//定义人被咬了以后的行为的方法,也即是回调方法</span></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">callBack</span><span class="params">()</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"人被狗咬了  好疼啊"</span>);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>Main方法实现整个回调过程：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CallMain</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</div><div class="line">        Person person = <span class="keyword">new</span> Person(<span class="keyword">new</span> Dog());</div><div class="line">        person.hitDog();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><a id="org0b3ab44"></a></p>
<h3 id="其次"><a href="#其次" class="headerlink" title="其次"></a>其次</h3><p>有了上述的栗子，想必大家对回调应该已经没有这么陌生了，接下来，我们再煮一个栗子，吃饱一点。</p>
<ol>
<li><p>模拟Android Onclick点击事件</p>
<ol>
<li><p><img src="http://olns0cxf5.bkt.clouddn.com/articleImages/rx/java-callback-2.png-RyanHuenBlog" alt="img"></p>
</li>
<li><p>代码实例：</p>
<ol>
<li><p>模拟Activity：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Activity</span> <span class="keyword">implements</span> <span class="title">OnClickListener</span> </span>&#123;</div><div class="line">    Button mButton;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 模拟Android的Activity中的onCreate()方法</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Activity</span><span class="params">(Button button)</span> </span>&#123;</div><div class="line">        <span class="comment">//模拟findViewById()</span></div><div class="line">        mButton = button;</div><div class="line">        mButton.setOnClickListener(<span class="keyword">this</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">()</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"按钮被点击了"</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="comment">/**</span></div><div class="line">     * 模拟Button点击</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">push</span><span class="params">()</span> </span>&#123;</div><div class="line">        mButton.performClick();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>模拟Button：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Button</span> </span>&#123;</div><div class="line">    OnClickListener mOnClickListener;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setOnClickListener</span><span class="params">(OnClickListener onClickListener)</span> </span>&#123;</div><div class="line">        mOnClickListener = onClickListener;</div><div class="line">    &#125;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">performClick</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="comment">//这就是回调</span></div><div class="line">        mOnClickListener.onClick();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>模拟点击事件的回调</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">OnClickListener</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">()</span></span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>模拟点击过程的main方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ClickMain</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</div><div class="line">        Activity activity=<span class="keyword">new</span> Activity(<span class="keyword">new</span> Button());</div><div class="line">        activity.push();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/RXJava系列/">RXJava系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/RxJava/">RxJava</a><a href="/tags/Java回调/">Java回调</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/14/JavaCallBack/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/14/JavaCallBack/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>






   
    
    <article class="post-expand post" itemprop="articleBody"> 
        <header class="article-info clearfix">
  <h1 itemprop="name">
    
      <a href="/2017/02/12/studio_debug_source/" title="Android Studio调试Android Framework源码" itemprop="url">Android Studio调试Android Framework源码</a>
  </h1>
  <p class="article-author">By
       
		<a href="/about" title="RyanHuen" target="_blank" itemprop="author">RyanHuen</a>
		
  <p class="article-time">
    <time datetime="2017-02-12T13:09:12.000Z" itemprop="datePublished"> 发表于 2017-02-12</time>
    
  </p>
</header>
    <div class="article-content">
        
        <p><a id="org4fa9c49"></a></p>
<h1 id="源码需要先编译一次"><a href="#源码需要先编译一次" class="headerlink" title="源码需要先编译一次"></a>源码需要先编译一次</h1><p><a id="org2746a08"></a></p>
<h2 id="编译环境配置"><a href="#编译环境配置" class="headerlink" title="编译环境配置"></a>编译环境配置</h2><pre><code>cd &lt;phoenix_root&gt;
source build/envsetup.sh
lunch aosp_flounder-userdebug（flounder:Nexus 9 flo Nexus 7二代 grouper Nexus 7一代）
</code></pre><p><a id="orgd73cc9a"></a></p>
<h2 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h2><p><a id="org04394e2"></a></p>
<h3 id="使用以下命令编译"><a href="#使用以下命令编译" class="headerlink" title="使用以下命令编译"></a>使用以下命令编译</h3><pre><code>make -j16(-j16 CPU核数)
</code></pre><p><a id="org287d687"></a></p>
<h1 id="生成android-ipr和android-iml文件"><a href="#生成android-ipr和android-iml文件" class="headerlink" title="生成android.ipr和android.iml文件"></a>生成android.ipr和android.iml文件</h1><ol>
<li><p>进入源码根目录</p>
<ol>
<li><p>执行：</p>
<ol>
<li><p>这行命令的意思是编译idegen这个项目,生成idegen.jar文件.生成成功后,会显示这个jar包的位置,并显示 #### make completed successfully</p>
<pre><code>mmm development/tools/idegen/
</code></pre></li>
</ol>
</li>
<li><p>执行：</p>
<ol>
<li><p>这行命令的意思是生成对应的文件:android.iws, android.ipr, android.iml</p>
<pre><code>sh ./development/tools/idegen/idegen.sh
</code></pre></li>
</ol>
</li>
</ol>
</li>
</ol>
<p><a id="org63a79c7"></a></p>
<h1 id="使用Studio调试源码"><a href="#使用Studio调试源码" class="headerlink" title="使用Studio调试源码"></a>使用Studio调试源码</h1><p><a id="org353535a"></a></p>
<h2 id="索引源码"><a href="#索引源码" class="headerlink" title="索引源码"></a>索引源码</h2><ol>
<li>File&#x2013;》Open&#x2013;》找到源码目录，打开android.ipr文件，Studio就会开始索引源码</li>
</ol>
<p><a id="org49651df"></a></p>
<h2 id="过滤源码"><a href="#过滤源码" class="headerlink" title="过滤源码"></a>过滤源码</h2><p><a id="orgb5d0eb0"></a></p>
<h3 id="过滤不需要的目录，加快索引速度："><a href="#过滤不需要的目录，加快索引速度：" class="headerlink" title="过滤不需要的目录，加快索引速度："></a>过滤不需要的目录，加快索引速度：</h3><ol>
<li><p>修改android.iml文件，可以去除或者添加需要Studio进行索引的目录</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/.repo"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/abi"</span> /&gt;</span></div></pre></td></tr></table></figure>
</li>
<li><p>上述代码标签表示我们指定某个目录不需要需要被Studio进行索引。索引后的目录中的java文件都会被Studio包含进来。</p>
<ol>
<li><p>索引时间比较长，大家着急的话，可以让Studio先索引着，继续往下看</p>
</li>
<li><p>到达这一步，源码可以看了，但是还不能调试</p>
</li>
</ol>
</li>
</ol>
<p><a id="orgc28b660"></a></p>
<h2 id="修改android-iml文件"><a href="#修改android-iml文件" class="headerlink" title="修改android.iml文件"></a>修改android.iml文件</h2><ol>
<li>细心的读者可能会发现Attach debugger to Android process按钮还不能启用。也就是目前还不能attach进程调试</li>
</ol>
<p><a id="org7f59113"></a></p>
<h3 id="我们需要修改android-iml文件。"><a href="#我们需要修改android-iml文件。" class="headerlink" title="我们需要修改android.iml文件。"></a>我们需要修改android.iml文件。</h3><ol>
<li>确保android.iml文件是如下代码开头，如果不是，需要修改成下面状态<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</div><div class="line"><span class="tag">&lt;<span class="name">module</span> <span class="attr">relativePaths</span>=<span class="string">"true"</span> <span class="attr">type</span>=<span class="string">"JAVA_MODULE"</span> <span class="attr">version</span>=<span class="string">"4"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">component</span> <span class="attr">name</span>=<span class="string">"FacetManager"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">facet</span> <span class="attr">type</span>=<span class="string">"android"</span> <span class="attr">name</span>=<span class="string">"Android"</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">configuration</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">facet</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">component</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">component</span> <span class="attr">name</span>=<span class="string">"NewModuleRootManager"</span> <span class="attr">inherit-compiler-output</span>=<span class="string">"true"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">exclude-output</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">content</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$"</span>&gt;</span></div><div class="line"> <span class="comment">&lt;!--到这里往下就是&lt;sourceFolder&gt;标签的内容了--&gt;</span></div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="org902fc64"></a></p>
<h3 id="关于-lt-sourceFolder-gt-标签"><a href="#关于-lt-sourceFolder-gt-标签" class="headerlink" title="关于&lt;sourceFolder&gt;标签"></a>关于&lt;sourceFolder&gt;标签</h3><ol>
<li>去除不需要debug的&lt;sourceFolder/&gt;标签内容,通常我们只需要frameworks和packages两个目录，所以保留这两个目录有关的标签就行，其他全部删掉，这样索引的速度就会加快了。</li>
</ol>
<p><a id="orge3e6898"></a></p>
<h3 id="关于-lt-excludeFolder-gt-标签"><a href="#关于-lt-excludeFolder-gt-标签" class="headerlink" title="关于&lt;excludeFolder&gt;标签"></a>关于&lt;excludeFolder&gt;标签</h3><ol>
<li><p>exclude顾名思义就是不包含的意思。我们有很多目录直接就不想让Studio去管它，不管是索引还是什么等等，所以只需要将这些目录配置到&lt;excludeFolder&gt;中就好了。</p>
</li>
<li><p>如下：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/.repo"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/abi"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/art"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/bionic"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/bootable"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/build"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/cts"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/dalvik"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/developers"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/development"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/device"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/docs"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/bluetooth"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/chromium"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/emma"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/icu4c"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/jdiff"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/webkit"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/docs"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/tests"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/tools"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/hardware"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/libcore"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/libnativehelper"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/ndk"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/out"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/pdk"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/platform_testing"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/prebuilt"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/sdk"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/tools"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/vendor"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/toolchain"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/system"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/prebuilts"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/phoenix"</span> /&gt;</span></div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="org88f6c13"></a></p>
<h3 id="关于-lt-orderEntry-gt-标签"><a href="#关于-lt-orderEntry-gt-标签" class="headerlink" title="关于&lt;orderEntry&gt;标签"></a>关于&lt;orderEntry&gt;标签</h3><ol>
<li><p>删除所有&lt;orderEntry /&gt;标签</p>
</li>
<li><p>删除以后添加以下两个：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">orderEntry</span> <span class="attr">type</span>=<span class="string">"sourceFolder"</span> <span class="attr">forTests</span>=<span class="string">"false"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">orderEntry</span> <span class="attr">type</span>=<span class="string">"jdk"</span> <span class="attr">jdkName</span>=<span class="string">"Android API 22 Platform"</span> <span class="attr">jdkType</span>=<span class="string">"Android SDK"</span> /&gt;</span></div></pre></td></tr></table></figure>
</li>
</ol>
<p><a id="org3139177"></a></p>
<h1 id="下面是修改的代码模板-大家可以参照一下"><a href="#下面是修改的代码模板-大家可以参照一下" class="headerlink" title="下面是修改的代码模板,大家可以参照一下"></a>下面是修改的代码模板,大家可以参照一下</h1><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</div><div class="line"><span class="tag">&lt;<span class="name">module</span> <span class="attr">relativePaths</span>=<span class="string">"true"</span> <span class="attr">type</span>=<span class="string">"JAVA_MODULE"</span> <span class="attr">version</span>=<span class="string">"4"</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">component</span> <span class="attr">name</span>=<span class="string">"FacetManager"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">facet</span> <span class="attr">type</span>=<span class="string">"android"</span> <span class="attr">name</span>=<span class="string">"Android"</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">configuration</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">facet</span>&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">component</span>&gt;</span></div><div class="line">  <span class="tag">&lt;<span class="name">component</span> <span class="attr">name</span>=<span class="string">"NewModuleRootManager"</span> <span class="attr">inherit-compiler-output</span>=<span class="string">"true"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">exclude-output</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">content</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$"</span>&gt;</span></div><div class="line">      <span class="comment">&lt;!--sourceFolder标签表示需要索引的代码目录--&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">sourceFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/core/java"</span> <span class="attr">isTestSource</span>=<span class="string">"false"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">sourceFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/gen"</span> <span class="attr">isTestSource</span>=<span class="string">"false"</span> <span class="attr">generated</span>=<span class="string">"true"</span> /&gt;</span></div><div class="line">      <span class="comment">&lt;!--excludeFolder标签表示这个目录下所有内容都不索引--&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/.repo"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/abi"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/art"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/bionic"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/bootable"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/build"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/cts"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/dalvik"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/developers"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/development"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/device"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/docs"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/bluetooth"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/chromium"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/emma"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/icu4c"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/jdiff"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/external/webkit"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/docs"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/tests"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/frameworks/base/tools"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/hardware"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/libcore"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/libnativehelper"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/ndk"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/out"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/pdk"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/platform_testing"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/prebuilt"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/sdk"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/tools"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/vendor"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/toolchain"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/system"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/prebuilts"</span> /&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">excludeFolder</span> <span class="attr">url</span>=<span class="string">"file://$MODULE_DIR$/phoenix"</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">content</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">orderEntry</span> <span class="attr">type</span>=<span class="string">"sourceFolder"</span> <span class="attr">forTests</span>=<span class="string">"false"</span> /&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">orderEntry</span> <span class="attr">type</span>=<span class="string">"jdk"</span> <span class="attr">jdkName</span>=<span class="string">"Android API 22 Platform"</span> <span class="attr">jdkType</span>=<span class="string">"Android SDK"</span> /&gt;</span></div><div class="line">  <span class="tag">&lt;/<span class="name">component</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">module</span>&gt;</span></div></pre></td></tr></table></figure>
<p><a id="org8f3d051"></a></p>
<h1 id="注意事项："><a href="#注意事项：" class="headerlink" title="注意事项："></a>注意事项：</h1><ol>
<li>如果想要在IDE中修改源码，需要关闭Android Studio的auto import功能，否则IDE会自动导入一些东西，会引起编译错误。原因未明。知道原因的小伙伴，麻烦不吝赐教啦。</li>
</ol>

        
        
        <p class="article-more-link">
          
       </p>
    </div>
    <footer class="article-footer clearfix">
<div class="article-catetags">

<div class="article-categories">
  <span></span>
  <a class="article-category-link" href="/categories/Framework系列/">Framework系列</a>
</div>


  <div class="article-tags">
  
  <span></span> <a href="/tags/Android-Studio/">Android Studio</a><a href="/tags/Framework/">Framework</a><a href="/tags/Debug/">Debug</a>
  </div>

</div>




<div class="comments-count">
	
	  	<span></span>
		<a href="/2017/02/12/studio_debug_source/#comments" class="ds-thread-count comments-count-link" data-thread-key="2017/02/12/studio_debug_source/" data-count-type="comments">&nbsp;</a>
	
</div>

</footer>


    </article>







  <nav id="page-nav" class="clearfix">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="extend next" rel="next" href="/page/2/">Next<span></span></a>
  </nav>

</div>
      <div class="openaside"><a class="navbutton" href="#" title="显示侧边栏"></a></div>

<div id="asidepart">
<div class="closeaside"><a class="closebutton" href="#" title="隐藏侧边栏"></a></div>
<aside class="clearfix">

  
<div class="categorieslist">
	<p class="asidetitle">分类</p>
		<ul>
		
		  
			<li><a href="/categories/Emacs系列/" title="Emacs系列">Emacs系列<sup>3</sup></a></li>
		  
		
		  
			<li><a href="/categories/Framework系列/" title="Framework系列">Framework系列<sup>1</sup></a></li>
		  
		
		  
			<li><a href="/categories/RXJava系列/" title="RXJava系列">RXJava系列<sup>7</sup></a></li>
		  
		
		  
			<li><a href="/categories/git入门系列/" title="git入门系列">git入门系列<sup>5</sup></a></li>
		  
		
		  
			<li><a href="/categories/Emacs系列/org-mode/" title="org-mode">org-mode<sup>1</sup></a></li>
		  
		
		</ul>
</div>


  
<div class="tagslist">
	<p class="asidetitle">标签</p>
		<ul class="clearfix">
		
			
				<li><a href="/tags/RxJava/" title="RxJava">RxJava<sup>7</sup></a></li>
			
		
			
				<li><a href="/tags/git/" title="git">git<sup>5</sup></a></li>
			
		
			
				<li><a href="/tags/RxJava基础/" title="RxJava基础">RxJava基础<sup>4</sup></a></li>
			
		
			
				<li><a href="/tags/Spacemacs/" title="Spacemacs">Spacemacs<sup>3</sup></a></li>
			
		
			
				<li><a href="/tags/Emacs/" title="Emacs">Emacs<sup>3</sup></a></li>
			
		
			
				<li><a href="/tags/观察者模式/" title="观察者模式">观察者模式<sup>3</sup></a></li>
			
		
			
				<li><a href="/tags/BackPressure/" title="BackPressure">BackPressure<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/org/" title="org">org<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/Java回调/" title="Java回调">Java回调<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/Debug/" title="Debug">Debug<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/设计模式/" title="设计模式">设计模式<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/RxJava操作符/" title="RxJava操作符">RxJava操作符<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/响应式编程/" title="响应式编程">响应式编程<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/Android-Studio/" title="Android Studio">Android Studio<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/Framework/" title="Framework">Framework<sup>1</sup></a></li>
			
		
			
				<li><a href="/tags/org-mode/" title="org-mode">org-mode<sup>1</sup></a></li>
			
		
		</ul>
</div>


  <div class="rsspart">
	<a href="/atom.xml" target="_blank" title="rss">RSS 订阅</a>
</div>

</aside>
</div>
    </div>
    <footer><div id="footer" >
	
	<div class="line">
		<span></span>
		<div class="author"></div>
	</div>
	
	
	<section class="info">
		<p> Hi there,I&#39;m RyanHuen <br/>
			A simple programmer</p>
	</section>
	 
	<div class="social-font" class="clearfix">
		
		<a href="http://weibo.com/ryanxuan" target="_blank" class="icon-weibo" title="微博"></a>
		
		
		<a href="https://github.com/RyanHuen" target="_blank" class="icon-github" title="github"></a>
		
		
		
		
		
		
		
		<a href="http://www.zhihu.com/people/ryan-hyn" target="_blank" class="icon-zhihu" title="知乎"></a>
		
		
		
		<a href="mailto:ryanhuenwork@163.com" target="_blank" class="icon-email" title="Email Me"></a>
		
	</div>
			
		

		<p class="copyright">
		Powered by <a href="http://hexo.io" target="_blank" title="hexo">hexo</a> and Theme by <a href="https://github.com/wuchong/jacman" target="_blank" title="Jacman">Jacman</a> © 2017 
		
		<a href="/about" target="_blank" title="RyanHuen">RyanHuen</a>
		
		
		</p>
</div>
</footer>
    <script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>
<script src="/js/jquery.qrcode-0.12.0.min.js"></script>

<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>
<script type="text/javascript">
$(document).ready(function(){ 
  $('.navbar').click(function(){
    $('header nav').toggleClass('shownav');
  });
  var myWidth = 0;
  function getSize(){
    if( typeof( window.innerWidth ) == 'number' ) {
      myWidth = window.innerWidth;
    } else if( document.documentElement && document.documentElement.clientWidth) {
      myWidth = document.documentElement.clientWidth;
    };
  };
  var m = $('#main'),
      a = $('#asidepart'),
      c = $('.closeaside'),
      o = $('.openaside');
  c.click(function(){
    a.addClass('fadeOut').css('display', 'none');
    o.css('display', 'block').addClass('fadeIn');
    m.addClass('moveMain');
  });
  o.click(function(){
    o.css('display', 'none').removeClass('beforeFadeIn');
    a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');      
    m.removeClass('moveMain');
  });
  $(window).scroll(function(){
    o.css("top",Math.max(80,260-$(this).scrollTop()));
  });
  
  $(window).resize(function(){
    getSize(); 
    if (myWidth >= 1024) {
      $('header nav').removeClass('shownav');
    }else{
      m.removeClass('moveMain');
      a.css('display', 'block').removeClass('fadeOut');
      o.css('display', 'none');
        
    }
  });
});
</script>










<link rel="stylesheet" href="/fancybox/jquery.fancybox.css" media="screen" type="text/css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script type="text/javascript">
$(document).ready(function(){ 
  $('.article-content').each(function(i){
    $(this).find('img').each(function(){
      if ($(this).parent().hasClass('fancybox')) return;
      var alt = this.alt;
      if (alt) $(this).after('<span class="caption">' + alt + '</span>');
      $(this).wrap('<a href="' + this.src + '" title="' + alt + '" class="fancybox"></a>');
    });
    $(this).find('.fancybox').each(function(){
      $(this).attr('rel', 'article' + i);
    });
  });
  if($.fancybox){
    $('.fancybox').fancybox();
  }
}); 
</script>



<!-- Analytics Begin -->



<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "//hm.baidu.com/hm.js?af124d045b4aed59105f75db52359992";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>



<!-- Analytics End -->

<!-- Totop Begin -->

	<div id="totop">
	<a title="返回顶部"><img src="/img/scrollup.png"/></a>
	</div>
	<script src="/js/totop.js"></script>

<!-- Totop End -->

<!-- MathJax Begin -->
<!-- mathjax config similar to math.stackexchange -->


<!-- MathJax End -->

<!-- Tiny_search Begin -->

<!-- Tiny_search End -->

  </body>
 </html>
